package ipc;

import ipc.State;
import java.util.List;
import java.util.ArrayList;
import java.util.Random;
import ipc.Simulator;
import ipc.Main;

    /**

     * Defines a general node in a UCT tree. The rewards_ field is lazily
     * initialized because its size isn't known until the first rewards vector
     * is passed to update.
     */

public abstract class Node<S extends State, A> {

	double MAXV = Double.NEGATIVE_INFINITY;
	double MINV = Double.POSITIVE_INFINITY;

        /** Rewards for each agent. */
        protected double[] rewards_ = null;

        /** Total number of visits to this node. */
        protected int visits_ = 0;

	protected List<Node<S,A>> children = null;

	public Node<S,A> getRandomChild(Random _rand){
		return children.get((int)(_rand.nextDouble()*children.size()));
	} 	

	public abstract Node<S,A> getMaxChild();



        public void update(double[] rewards) {
	
            if (rewards_ == null)
                rewards_ = new double[rewards.length];
            visits_++;
            for (int i = 0; i < rewards.length; i++){
                rewards_[i] += rewards[i];
		if( rewards[i]/visits_ > MAXV )
			MAXV = rewards[i]/visits_;
		if( rewards[i]/visits_ < MINV )
			MINV = rewards[i]/visits_;
            }

        }

        public int getVisits() {
            return visits_;
        }

        /**
         * Get the reward for the specified agent.
         * 
         * @param agentId
         *            agent identifier.
         * @return accumulated reward for specified agent.
         * @throws NullPointerException
         *             if visits_ < 1.
         */
        public double getReward(int agentId) {
        	if( this.visits_ < 1){
        		Main.exceptionLog.log("Asking reward for an unvisited state??");
        	}
            return rewards_[agentId];
        }

	public abstract Node<S,A> selectChild(Simulator<S,A> sim, Random _rand, int depth);

	public  Node<S,A> getChild(S state, List<A> legals) throws Exception{
		throw new RuntimeException("wrong place");
	} 
    }
